package com.guoqing.example.streams;

import com.sun.javafx.binding.StringFormatter;

import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author zhangguoqing
 * @date 2020/9/23
 * Description: TODO
 */
public class MyStream {

    public static void main02(String[] args) {
        // stream 去重
        List<User> users = new ArrayList<>();
        users.add(new User("A", "a", 1));
        users.add(new User("B", "d,e,f", 1));
//        Map<String, String> collect = users.stream().collect(Collectors.toMap(User::getId, User::getName));
        Map<String, String[]> collect = users.stream().collect(Collectors.toMap(o -> o.getId(), o -> o.getName().split(",")));
        System.out.println(collect);
        System.out.println(collect.containsValue("e"));

        String a = "1,2,3,4,5";
        Map<String, String> specMap = new HashMap<>();
        specMap.put("1", "a");
        specMap.put("2", "b");
        specMap.put("3", "c");
        specMap.put("4", "d");
        specMap.put("5", "e");
        List<String> content = new ArrayList<>();
        for (String str : a.split(",")) {
            String spec = specMap.get(str);
            content.add(StringFormatter.format("\"%s\":\"%s\"", spec, str).get());
        }
        String join = String.join(",", content);
        System.out.println("{" + join + "}");
    }

    public static void main(String[] args) {
        List<User> returnItemColl = new ArrayList<>();
        returnItemColl.add(new User().setId("1001").setAge(10).setFNum(new BigDecimal("11")));
        returnItemColl.add(new User().setId("1002").setAge(10).setFNum(new BigDecimal("11")));
        returnItemColl.add(new User().setId("1003").setAge(20).setFNum(new BigDecimal("22")));
        returnItemColl.add(new User().setId("1001").setAge(30).setFNum(new BigDecimal("33")));

        Map<String, Integer> collect = returnItemColl.stream().
                collect(Collectors.groupingBy(User::getId,
                        Collectors.summingInt(User::getAge)));
        System.out.println(collect);

        Map<String, BigDecimal> collect1 = returnItemColl.stream()
                .collect(Collectors.groupingBy(User::getId,
                        Collectors.mapping(User::getFNum,
                                Collectors.reducing(BigDecimal.ZERO, BigDecimal::add))));
        System.out.println(collect1);

    }

    public static void main01(String[] args) {
        List<User> users = new ArrayList<>();
        users.add(new User("A", "张三", 1));
        users.add(new User("A", "张三2", 4));
        users.add(new User("B", "张三", 2));
        users.add(new User("C", "李四", 3));
        users.add(new User("A", "张三", 3));
        Supplier<Stream<User>> supplier = users::stream;

        // 按照 age 降序
        List<User> collect7 = supplier.get().sorted(Comparator.comparing(User::getAge).reversed()).collect(Collectors.toList());
        System.out.println(collect7);
        // 求和
        int sum = supplier.get().mapToInt(User::getAge).sum();
        // 求 最大值
        int asInt = supplier.get().mapToInt(User::getAge).max().getAsInt();
        // 求 最小值
        int asInt1 = supplier.get().mapToInt(User::getAge).min().getAsInt();
        // 求 平均值
        double asDouble = supplier.get().mapToInt(User::getAge).average().getAsDouble();
        // list 转 Map， key = id, 去重
        Map<String, User> collect = supplier.get().collect(Collectors.toMap(User::getId, Function.identity(), (obj1, obj2) -> obj2));
        // list 根据对象的属性去重数据
        ArrayList<User> users1 = supplier.get().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(User::getId))), ArrayList::new));
        ArrayList<User> users2 = supplier.get().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(u -> u.getId()+u.getName()))), ArrayList::new));
        // 分组
        Map<String, List<User>> collect1 = supplier.get().collect(Collectors.groupingBy(User::getId));
        // 分组后 根据属性值求和
        Map<String, Double> collect2 = supplier.get().collect(Collectors.groupingBy(User::getId, Collectors.summingDouble(User::getAge)));
        // 分组后 求 每个 key 对应 value 的 数量
        Map<String, Long> collect3 = supplier.get().collect(Collectors.groupingBy(User::getId, Collectors.counting()));
        // 根据 ID 分组后 又 对 每个 value 进行 分组
        Map<String, Map<String, Long>> collect4 = supplier.get().collect(Collectors.groupingBy(User::getId, Collectors.groupingBy(User::getName, Collectors.counting())));
        Map<String, Map<String, Integer>> collect5 = supplier.get().collect(Collectors.groupingBy(User::getId, Collectors.groupingBy(User::getName, Collectors.summingInt(User::getAge))));
        Map<String, Map<String, List<User>>> collect6 = supplier.get().collect(Collectors.groupingBy(User::getId, Collectors.groupingBy(User::getName)));

        Map<String, Map<String, Integer>> stringMapMap = sortMap(collect5);
        Map<String, Map<String, Integer>> stringMapMap2 = sortMap2(collect5);System.out.println("s");

    }

    public static <K extends Comparable<? super K>, V> Map<K, V> sortMap(Map<K, V> map){
        Map<K, V> linkedHashMap = new LinkedHashMap<>();
        map.entrySet().stream().sorted(Map.Entry.<K, V>comparingByKey())
                .forEachOrdered( e -> linkedHashMap.put(e.getKey(), e.getValue()));
        return linkedHashMap;
    }

    public static <K extends Comparable<? super K>, V> Map<K, V> sortMap2(Map<K, V> map){
        Map<K, V> linkedHashMap = new LinkedHashMap<>();
        map.entrySet().stream().sorted(Map.Entry.<K, V>comparingByKey().reversed())
                .forEachOrdered( e -> linkedHashMap.put(e.getKey(), e.getValue()));
        return linkedHashMap;
    }


}
